#!/opt/ActivePerl-5.14/bin/perl

use DBI;
use Carp;
use strict;
use warnings;
use Switch;
use Net::FTP;
use File::Copy;
use Getopt::Long;
use File::Basename;
use XML::Simple qw(:strict);
use Mail::Sender::Easy qw(email);

my (
    $config,  $options,   $xml,   $ftp,   $file,
    $sbj,     @globfiles, @files, %fail,  @missing,
    %fdelete, %adelete,   $msg,   $error, @uploaded
);
my $e = 1;
$options = GetOptions( 'config=s' => \$config );

if ( -e $config ) {

    $xml = XMLin( $config, ForceArray => 0, KeyAttr => [] );
    open LOG, ">>$xml->{logfile}" or croak;
    print {*LOG} "\nJob : $xml->{job} \nStart Time: "
      . localtime() . "\n"
      . "Job type : $xml->{type}" . "\n"
      or croak;
    print {*LOG}
"------------------------------------------------------------------------------------------\n"
      or croak;
    print {*LOG} "found $config file.\n" or croak;
}

else {
    print "The config file you specified was not found.\n" or croak;
    exit;
}

$ftp = Net::FTP->new( $xml->{host}, Timeout => 360, Debug => 0 );
if ( $@ ne "" ) {

    print {*LOG}
      "There was a problem establishing a connection to $xml->{host}.\n"
      or croak;
    print {*LOG} "FTP Server Message : " . $@ . "\n" or croak;
    $error = "Automize failed to connect to $xml->{host}. \n";
    $error =
        $error
      . "The FTP Server returned the following error message. \n"
      . $@ . "\n\n";
    $error = $error . "Thank you,\n" . "Automize Server\n";
    $sbj   = "Error - $xml->{job} failed to connect to $xml->{host}";
    UPDATE(0);
    EMAIL( $error, $sbj );
    exit;
}

unless ( $ftp->login( $xml->{user}, $xml->{password} ) ) {
    print {*LOG} "Login to $xml->{host} was not successful.\n" or croak;
    print {*LOG} "The message from FTP server is : \n"         or croak;
    print {*LOG} $ftp->message . "\n"                          or croak;
    $error = "Error - $xml->{job} job failed to login to $xml->{host}. \n";
    $error = $error . "Check the username and password. \n";
    $error = $error . "Here is the error message from the FTP server : \n";
    $error = $error . $ftp->message . " \n\n" . "Thank you, \n" . 'Automize Server';
    $sbj = "Error - Job $xml->{job} Failed. Could not login to $xml->{host}.";
    UPDATE(0);
    EMAIL( $error, $sbj );
    exit;
}

switch ( $xml->{type} ) {
    case 'upload' {

        print {
            *LOG
        }
        "Uploads :\n" or croak;
        print {*LOG}
"---------------------------------------------------------------------------------------\n"
          or croak;

        if ( exists $xml->{files}->{file} ) {
            push @files, $xml->{files}->{file}
              if ( ref( $xml->{files}->{file} ) eq "" );
            if ( ref( $xml->{files}->{file} ) eq 'ARRAY' ) {
                foreach $file ( @{ $xml->{files}->{file} } ) {
                    push @files, $file;
                }
            }
        }

        elsif ( exists $xml->{files}->{regex} ) {
            @globfiles = glob("$xml->{localpath}/$xml->{files}->{regex}");
        }

        else {
            print {*LOG}
"Please check the $config file there are no files listed for $xml->{type} job.\n"
              or croak;
            $error =
"Please check the $config file did not find any files listed to be $xml->{type}ed.\n";
            $error .= "Thank you, \n" . "Automize Server\n";
            $sbj = "Error - The config file for $xml->{job} is not valid.";
            UPDATE(0);
            EMAIL( $error, $sbj );
            exit;
        }

        unless ( $ftp->cwd( $xml->{serverpath} ) ) {
            print {*LOG}
"There is a problem trying to open $xml->{serverpath} on the server.\n"
              or croak;
            print {*LOG}
              "The FTP server returned the following error message : \n"
              . $ftp->message . "\n\n"
              or croak;
            $error =
"There is a problem trying to open $xml->{serverpath} on the server.\n";
            $error .= "The FTP server returned the following error message : \n"
              . $ftp->message . "\n\n";
            $error .= "Thank you, \n" . "Automize Server\n";
            $sbj =
"Error - $xml->{job} failed. $xml->{serverpath} could not be opened on $xml->{host}";
            UPDATE(0);
            EMAIL( $error, $sbj );
            exit;
        }

        $ftp->binary();

        if ( scalar(@files) > 0 ) {

            foreach $file (@files) {

                if ( exists $xml->{ok} && $file eq $xml->{ok} ) {
                    UPDATE(1);
                    next;
                }
				
				if ( exists $xml->{checkfile}){
					if ( !-e $xml->{checkfile} ){
						exit;
					}
				}

                unless ( -e "$xml->{localpath}/$file" ) {
                    push @missing, $file;
                    print {*LOG} $file . " does not exist. \n" or croak;
                    next;
                }

                my (
                    $dev,   $ino,     $mode, $nlink, $uid,
                    $gid,   $rdev,    $size, $atime, $mtime,
                    $ctime, $blksize, $blocks
                ) = stat "$xml->{localpath}/$file";
                if ( $size == 0 ) {
                    EMAIL(
"$file is zero bytes in size.\n\nThank you,\nAutomize Server",
                        "Error: $xml->{job}"
                    );
                    next;
                }

                eval {

                    if ( exists $xml->{name} ) {
						if( exists $xml->{count}){
							COUNTLINES("$xml->{localpath}/$file");
						}
                        $ftp->put( "$xml->{localpath}/$file", $xml->{name} )
                          or die $ftp->message . "\n";
                        print {*LOG} "$file ===> $size"
                          . "bits ==> Uploaded ok.\n"
                          or croak;
						  
						if ( exists $xml->{checkfile}){
						
							unlink( $xml->{checkfile} );
						}

                        if ( exists $xml->{email} ) {

                            ( my $lname, my $lpath, my $lsuffix ) =
                              fileparse( $file, qr/\.[^.]*/ );
                            my $lfile = $lname . $lsuffix;
                            push @uploaded, $lfile;
                        }
                    }

                    else {
						if( exists $xml->{count}){
							COUNTLINES("$xml->{localpath}/$file");
						}
                        $ftp->put("$xml->{localpath}/$file")
                          or die $ftp->message . "\n";
                        print {*LOG} "$file ===> $size"
                          . "bits ==> Uploaded ok.\n"
                          or croak;
  
						if ( exists $xml->{checkfile}){
						
							unlink( $xml->{checkfile} );
						}
						
                        if ( exists $xml->{email} ) {

                            ( my $sname, my $spath, my $ssuffix ) =
                              fileparse( $file, qr/\.[^.]*/ );
                            my $nfile = $sname . $ssuffix;
                            push @uploaded, $nfile;
                        }
                    }
                };

                if ($@) {

                    $fail{$file} = 'Upload failed ' . $@;
                }
            }

            if ( scalar @uploaded > 0 ) {

                my $pfiles = join "\n", @uploaded;
                print {*LOG}
"Email notification sent to $xml->{email} regarding $xml->{job}."
                  or croak;
                NOTIFY( $xml->{email},
                    'There are new files waiting to process.', $pfiles );

            }

            unless ( $ftp->close ) {

                print {*LOG}
                  "Connection to $xml->{host} was not closed correctly.\n"
                  or croak;
                print {*LOG}
                  "The FTP server returned the following error message : \n "
                  . $ftp->message
                  or croak;
                $error = "Connection to server was not closed correctly. \n";
                $error = $error
                  . "This may or may not present a problem if error persist contact help desk.\n";
                $error = $error
                  . "The FTP server returned the following message $ftp->message\n\n";
                $error = $error . "Thank you, \n" . "Automize Server \n";
                $sbj =
"Warning - Connection to $xml->{host} was not closed correctly.";
                if ( $e == 1 ) { $e = 2; }
                EMAIL( $error, $sbj );
            }

            unless ( scalar(@missing) == 0 ) {

                print {*LOG} join "\n", @missing . " is missing.\n" or croak;
                $error = "The following files could not be found. \n";
                $error =
                    $error
                  . join( "\n", @missing ) . "\n\n"
                  . "Thank you, \n"
                  . "Automize Server \n";
                $sbj = "Warning - job $xml->{job}. Files not found.";
                if ( $e == 1 ) { $e = 2; }
                EMAIL( $error, $sbj );
            }

            unless ( keys(%fail) == 0 ) {

                $msg = "The following files failed to upload.\n";
                $msg = $msg . join "\n", %fail;
                $msg = $msg . "\nThank you,\n" . 'Automize Server';
                $sbj = "Warning - Job $xml->{job} ran with errors.";
                if ( $e == 1 ) { $e = 2; }
                EMAIL( $msg, $sbj );
            }

            if ( exists $xml->{historypath} ) { ARCHIVE(@files); }
            print {*LOG} "$xml->{job} completed successfully.\n" or croak;
        }

        elsif ( scalar(@globfiles) > 0 ) {

            foreach $file (@globfiles) {

                if ( exists $xml->{ok} && $file eq "$xml->{localpath}/$xml->{ok}" )
				{
                    UPDATE(1);
                    next;
                }
				
				if ( exists $xml->{checkfile}){
					if ( !-e $xml->{checkfile} ){
						exit;
					}
				}
				
				if( exists $xml->{count}){
					COUNTLINES($file);
				}

                unless ( -e $file ) {

                    push @missing, $file;
                    print {*LOG} $file . " no found. \n" or croak;
                    next;
                }

                my (
                    $dev,   $ino,     $mode, $nlink, $uid,
                    $gid,   $rdev,    $size, $atime, $mtime,
                    $ctime, $blksize, $blocks
                ) = stat $file;
                if ( $size == 0 ) {
                    EMAIL(
"$file is zero bytes in size.\n\nThank you,\nAutomize Server",
                        "Error: $xml->{job}"
                    );
                    next;
                }

                if ( $xml->{track} == 1 ) {
                    TRACK($file);
                }

                unless ( $ftp->put($file) ) {

                    $fail{$file} = "Upload failed.\n" . $ftp->message;
                    print {*LOG} $file . ' => ' . $fail{$file} . " failed\n"
                      or croak;
                    next;
                }
  
				if ( exists $xml->{checkfile}){
						
					unlink( $xml->{checkfile} );
				}
				
                if ( exists $xml->{email} ) {

                    ( my $gname, my $gpath, my $gsuffix ) =
                      fileparse( $file, qr/\.[^.]*/ );
                    my $gfile = $gname . $gsuffix;
                    push @uploaded, $gfile;
                }

                print {*LOG} "$file ===> $size" . "Bits ==> uploaded ok.\n"
                  or croak;
            }

            if ( scalar @uploaded > 0 ) {

                my $pfiles = join "\n", @uploaded;
                print {*LOG}
"Email notification sent to $xml->{email} regarding $xml->{job}."
                  or croak;
                NOTIFY( $xml->{email},
                    'There are new files waiting to process.', $pfiles );

            }

            unless ( $ftp->close ) {

                print {*LOG}
                  "Connection to $xml->{host} was not closed correctly.\n"
                  or croak;
                print {*LOG}
                  "The FTP server returned the following error message : \n "
                  . $ftp->message
                  or croak;
                $error = "Connection to server was not closed correctly. \n";
                $error .=
"This may or may not present a problem if error persist contact help desk.\n";
                $error .= 'The FTP server returned the following message '
                  . $ftp->message . "\n\n";
                $error .= "Thank you, \n" . "Automize Server \n";
                $sbj =
"Warning - Connection to $xml->{host} was not closed correctly.";
                if ( $e == 1 ) { $e = 2; }
                EMAIL( $error, $sbj );
            }

            unless ( scalar(@missing) == 0 ) {

                $error = "The following files could not be found. \n";
                $error .=
                    join( "\n", @missing ) . "\n\n"
                  . "Thank you, \n"
                  . "Automize Server \n";
                $sbj = "Warning - job $xml->{job}. Files not found.";
                if ( $e == 1 ) { $e = 2; }
                EMAIL( $error, $sbj );
            }

            unless ( keys(%fail) == 0 ) {

                $msg = "The following files failed to upload.\n";
                $msg .= join "\n", %fail;
                $msg .= "\nThank you,\n" . 'Automize Server';
                $sbj = "Warning - Job $xml->{job} ran with errors.";
                if ( $e == 1 ) { $e = 2; }
                EMAIL( $msg, $sbj );
            }

            print {*LOG} "Connection to $xml->{host} closed successfully. \n"
              or croak;
            if ( exists $xml->{historypath} ) { ARCHIVE(@globfiles); }
            print {*LOG} "$xml->{job} completed successfully.\n" or croak;
        }

        else {

            print {*LOG} "No files found to $xml->{type}.\n" or croak;
            $error = "No files found to $xml->{type}.\n";
            $error .= "Thank you, \n" . "Automize Server \n";
            $sbj = "Error : $xml->{job}. No files found to $xml->{type}.";
            UPDATE(0);
            EMAIL( $error, $sbj );
            exit;
        }
    }


    case 'download' {

        print {*LOG} "\nDownloads :\n" or croak;
        print {*LOG} "---------------------------------------------------------------------------------------\n" or croak;

        unless ( $ftp->cwd( $xml->{serverpath} ) ) {

            print {*LOG} "Path not found.\n" . $ftp->message or croak;
            $error = "Could not find $xml->{serverpath} on $xml->{host}.\n\n";
            $error .= "Thank you,\n" . "Automzie Server\n";
            $sbj = "Error - $xml->{job} failed.";
            UPDATE(0);
            EMAIL( $error, $sbj );
            exit;
        }

        if ( exists $xml->{files}->{file} ) {

            #print $xml->{files}->{file} . "\n";
            push @files, $xml->{files}->{file} if ( ref( $xml->{files}->{file} ) eq "" );
            @files = ( @{ $xml->{files}->{file} } ) if ( ref( $xml->{files}->{file} ) eq "ARRAY" );

            #print scalar @files . "\n";
        }

        elsif ( exists $xml->{files}->{regex} ) {
            @files = $ftp->ls($xml->{files}->{regex});
        }

        else {
            @files = $ftp->ls;
            if ( scalar @files == 0 ) {

                #print { *LOG } "no files found.\n" . $ftp->message or croak;
                $error = "No files found to download.\n";
                $error .= "\nThank you,\nAutomize Server";
                $sbj = "Error - $xml->{job} failed. No files found.";
                UPDATE(0);
                EMAIL( $error, $sbj );
                exit;
            }
        }

        foreach $file (@files) {
            #print $file . "\n";

            unless ( $ftp->get( $file, "$xml->{localpath}/$file" ) ) {

                $fail{$file} = "download failed. \nserver message: " . $ftp->message;
                print {*LOG} $file . " " . $fail{$file} . " download failed.\n" or croak;
                next;
            }

            print {*LOG} "$file was downloaded to $xml->{localpath}\n" or croak;

            if ( -e "$xml->{localpath}/$file" ) {

                if( exists $xml->{del} && $xml->{del} == 0 ){next;}
                unless ( $ftp->delete($file) ) {
                    $fdelete{$file} = $ftp->message;
                    next;
                }
            }
        }

        unless ( $ftp->close ) {

            print {*LOG} "Connection to $xml->{host} was not closed correctly.\n" or croak;
            print {*LOG} "The FTP server returned the following error message : \n $ftp->message" or croak;
            $error = "Connection to server was not closed correctly. \n";
            $error .= "The FTP server returned the following message $ftp->message\n\n";
            $error .= "Thank you, \n" . "Automize Server \n";
            $sbj = "Warning - Connection to $xml->{host} was not closed correctly.";
            if ( $e == 1 ) { $e = 2; }
            EMAIL( $error, $sbj );
        }

        unless ( keys(%fdelete) == 0 ) {
            print {*LOG} "The following files failed to be deleted from $xml->{host}. \n" or croak;
            print {*LOG} "Check that the files were downloaded correctly. \n" or croak;
            $error = "The following files failed to be deleted from $xml->{host}. \n";
            $error .= "Check that the files were downloaded correctly. \n";
            $error .= join "\n", %fdelete;
            $error .= "Thank you, \n" . "Automize Server \n";
            $sbj = "Warning - $xml->{job} - There was a problem deleting files from $xml->{host}";
            if ( $e == 1 ) { $e = 2; }
            EMAIL( $error, $sbj );
        }

        unless ( keys(%fail) == 0 ) {
            $msg = "The following files failed to download.\n";
            $msg .= join "\n", %fail;
            $msg .= "\nThank you,\n" . 'Automize Server';
            $sbj = "Warning - Job $xml->{job} ran with errors.";
            if ( $e == 1 ) { $e = 2; }
            EMAIL( $msg, $sbj );
        }

        print {*LOG} "Closed ftp connection to $xml->{host}\n" or croak;

        #if(exists $xml->{historypath}){ARCHIVE(@files);}
    }

    else {

        $ftp->close;
        print {*LOG} "Please specify what type of job this is. Either a \n" or croak;
        $error = "What type of ftp transfer is this. There is no type specified in XML file.\n\n";
        $error = $error . "Thank you,\n" . "Automize Server\n";
        UPDATE(0);
        EMAIL( $error, $sbj );
        close LOG or croak;
        exit;
    }
}

print {*LOG} "$xml->{job} completed successfully.\n" or croak;
UPDATE($e);

#print $e . "\n" or croak;
close LOG or croak;

sub ARCHIVE {

    ( my @archive ) = @_;
    print {*LOG} "History : \n" or croak;
    print {*LOG} "---------------------------------------------------------------------------------------\n" or croak;

    if ( exists $xml->{date} ) {

        if ( $xml->{date} == 0 ) {

            foreach my $history (@archive) {

                ( my $n, my $p, my $s ) = fileparse( $history, qr/\.[^.]*/ );

                if ( $p eq "./" ) {

                    if ( copy( "$xml->{localpath}/$history", "$xml->{historypath}/$history" ) == 0 )
                    {
                        $adelete{$history} = $!;
                        print {*LOG} "$history file could not be moved to $xml->{historypath}\n" or croak;
                        next;
                    }

                    if ( exists $xml->{del} && $xml->{del} == 1 ) {
                        unless ( unlink "$xml->{localpath}/$history" ) {
                            print {*LOG} "$history file was not deleted from $xml->{localpath}.\n" or croak;
                            print {*LOG} $! . "\n" or croak;
                            next;
                        }
                    }

                    print {*LOG} "$history was successfully moved to $xml->{historypath}\n" or croak;
                }

                elsif ( $p eq "$xml->{localpath}/" ) {

                    if ( copy( $history, "$xml->{historypath}/" ) == 0 ) {
                        $adelete{$history} = $!;
                        print {*LOG} "$history file could not be moved to $xml->{historypath}\n" or croak;
                        next;
                    }

                    if ( exists $xml->{del} && $xml->{del} == 1 ) {
                        unless ( unlink $history ) {
                            print {*LOG} "$history file was not deleted from $xml->{localpath}.\n" or croak;
                            print {*LOG} $! . "\n" or croak;
                            next;
                        }
                    }

                    print {*LOG} "$history was successfully moved to $xml->{historypath}\n" or croak;
                }

                else {
                    print {*LOG} "Could not compare the history perameters. Please check. \n" or croak;
                }
            }
        }

        elsif ( $xml->{date} == 1 ) {

            foreach my $history (@archive) {

                ( my $n, my $p, my $s ) = fileparse( $history, qr/\.[^.]*/ );
                use POSIX qw(strftime);
                my $timestamp = strftime "%b-%e-%H-%M", localtime;
                my $newfile = $n . "-" . $timestamp . $s;

                if ( copy("$xml->{localpath}/$history", "$xml->{historypath}/$newfile" ) == 0 )
                {
                    $adelete{$history} = $!;
                    print {*LOG} "Could not move $history to $xml->{historypath}.\n" or croak;
                    print {*LOG} $! . "\n" or croak;
                    next;
                }

                if ( exists $xml->{del} && $xml->{del} == 1 ) {
                    unless ( unlink "$xml->{localpath}/$history" ) {
                        print {*LOG} "Could not delete $history from $xml->{localpath}.\n" or croak;
                        print {*LOG} $! . "\n" or croak;
                        next;
                    }
                }
                print {*LOG} "$history file was successfully moved to $xml->{historypath}\n" or croak;
            }
        }
        else {
            print {*LOG} "XML file missing date specification.\n" or croak;
            $error = "Specify whether to append a timestamp to file before moving to history folder. \n\n";
            $error = $error . "Thank you, \n" . "Automize Server\n";
            $sbj = 'Warning - There was a problem when moving files to history folder.';
            UPDATE(2);
            EMAIL( $error, $sbj );
        }
    }
}

sub EMAIL {
    my ( $emsg, $esbj ) = @_;
    email(
        {
            'from'     => 'automize@brighton.com',
            'to'       => 'autoerrors@brighton.com',
            'replyto'  => 'lcruz@brighton.com',
            'subject'  => $esbj,
            'priority' => 1,                           # 1-5 high to low
            'confirm'  => 'delivery',
            'smtp'     => '128.222.78.145',
            'port'     => 25,
            'auth'     => 'LOGIN',
            'authid'   => 'leegin\automize',
            'authpwd'  => 'ariel',
            '_text'    => $emsg,
        }
    );

    print {*LOG} "Email sent.\n" or croak;
    return 1;
}

sub NOTIFY {

    my ( $mailto, $sub, $mfiles ) = @_;
    my $messg = "The following files are waiting to be processed.\n\n$mfiles\n";
    $messg .= "\nThank You,\nAutomize Server";

    email(
        {
            'from'     => 'automize@brighton.com',
            'to'       => $mailto,
            'replyto'  => 'helpdesk@brighton.com',
            'subject'  => $sub,
            'priority' => 1,                         # 1-5 high to low
            'confirm'  => 'delivery',
            'smtp'     => '128.222.78.145',
            'port'     => 25,
            'auth'     => 'LOGIN',
            'authid'   => 'leegin\automize',
            'authpwd'  => 'ariel',
            '_text'    => $messg,
        }
    );
    return 1;
}

sub UPDATE {

    my ($umsg) = @_;
    my ( $n, my $p ) = fileparse( $xml->{logfile} );
    my $dbh = DBI->connect( 'DBI:mysql:automize:localhost', 'automize', 'green97', { RaiseError => 1, AutoCommit => 1 } );
    my $sql = " UPDATE cron SET ok=$umsg, log=\"$n\", ran_at=" . time() . " WHERE job=\"$xml->{job}\" " or croak;
    my $sth = $dbh->prepare($sql) or die "Failed: $sql\n";
    my $rv = $sth->execute;
    $dbh->disconnect;
    return 1;
}

sub TRACK {

    my ($file) = @_;
    my ( $fname, my $fpath ) = fileparse($file);
    my (
        $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
        $size, $atime, $mtime, $ctime, $blksize, $blocks
    ) = stat($file);
    my $dbh = DBI->connect( 'DBI:mysql:automize:localhost','automize', 'green97', { RaiseError => 1, AutoCommit => 1 } );
    my $sql = " SELECT cron_id FROM cron WHERE job=\"$xml->{job}\" " or croak;
    my $sth = $dbh->prepare($sql) or die "Failed: $sql\n";
    my $rv  = $sth->execute;
    my @row = $sth->fetchrow_array();
    $sth->finish;
    $dbh->disconnect;

    $dbh = DBI->connect( 'DBI:mysql:automize:localhost','automize', 'green97', { RaiseError => 1, AutoCommit => 1 } );
    $sql = 'INSERT INTO processed VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ? ) ';
    $sth = $dbh->prepare($sql) or die "Failed: $sql\n";
    $rv = $sth->execute( 'DEFAULT', $row[0], $fname, $size, $ctime, time, 0, 0, 1 );
    $dbh->disconnect;

    return 1;
}
sub COUNTLINES {

	my ($brifile) = @_;	
	( my $Bname, my $Bpath, my $Bsuffix ) = fileparse( $brifile, qr/\.[^.]*/ );
	my $checked = $Bname . '-CHECKED.csv';

	open FH, "$brifile";
		my @tmpBri = <FH>;
	close FH;

	my $lastval = uc(pop(@tmpBri));

	if(substr($lastval,0,3) eq 'END'){
		open NF, ">>/temp/bri-ship/brighton/$checked";
			print NF scalar(@tmpBri);
		close NF;
	}
	else{
		print $brifile . " is missing end of file marker.\n";
	}
}
